This patch is intended to correct the number of CPUs.
authordjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Wed, 21 Dec 2005 14:53:40 +0000 (08:53 -0600)
committerdjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Wed, 21 Dec 2005 14:53:40 +0000 (08:53 -0600)
Our IPF machines are the following configurations.
 - Total logical cpus = 16
  -- 4 sockets
  -- 2 cores
  -- 2 threads

I changed the setting of BIOS, and invalidated the hyperthread, and I built Xen with NR_CPUS=8.
As a result, it became like attached file xendmesg1.txt.
 - Available cpus 3
 - Total cpus 8

Next, I built Xen with NR_CPUS=16.
As a result, it became like attached file xendmesg2.txt.
 - Available cpus 8
 - Total cpus 16

I thought not to match the analysis of the lsapic entry to the value of NR_CPUS.

It is an outline of patch as follows.
 1. Count up the lsapic entry by using acpi_table_count_madt()/acpi_table_count_madt_family().
 2. Call acpi_parse_lsapic() by using the number of lsapic entries.
 3. Count up the available_cpus by using acpi_parse_lsapic(), however NR_CPUS is not exceeded.

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Best Regards,
 Kan

xen/arch/ia64/xen/acpi.c
xen/drivers/acpi/tables.c
xen/include/xen/acpi.h

index f0eab76870a01dd1ddfe02500aac143bb246eff9..d307c44a52308a3750ee2fb86eba80c2f894591c 100644 (file)
@@ -203,12 +203,18 @@ acpi_parse_lsapic (acpi_table_entry_header *header, const unsigned long end)
        else {
                printk(" enabled");
 #ifdef CONFIG_SMP
-               smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid;
-               if (hard_smp_processor_id()
-                   == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus])
-                       printk(" (BSP)");
-#endif
+               if (available_cpus < NR_CPUS) {
+                       smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid;
+                       if (hard_smp_processor_id()
+                           == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus])
+                               printk(" (BSP)");
+                       ++available_cpus;
+               } else {
+                       printk(" - however, ignored...");
+               }
+#else
                ++available_cpus;
+#endif
        }
 
        printk("\n");
@@ -598,8 +604,17 @@ acpi_boot_init (void)
        if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0) < 0)
                printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
 
+#ifdef CONFIG_SMP
+       int count;
+       if ((count = acpi_table_count_madt(ACPI_MADT_LSAPIC)) < 1) {
+               printk(KERN_ERR PREFIX "Error parsing MADT - no LSAPIC entries\n");
+       } else {
+               acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic, count);
+       }
+#else
        if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic, NR_CPUS) < 1)
-               printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
+               printk(KERN_ERR PREFIX "Error parsing MADT - no LSAPIC entries\n");
+#endif
 
        if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0) < 0)
                printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
index 1c718efc889cfdcc267ca3f25246d81e3b36e2fc..837aa0d321c602040f141351b39ee73c18f60cb3 100644 (file)
@@ -607,3 +607,60 @@ acpi_table_init (void)
 
        return 0;
 }
+
+int __init
+acpi_table_count_madt_family (
+       enum acpi_table_id      id,
+       unsigned long           madt_size,
+       int                     entry_id)
+{
+       void                    *madt = NULL;
+       acpi_table_entry_header *entry;
+       unsigned int            count = 0;
+       unsigned long           madt_end;
+       unsigned int            i;
+
+       /* Locate the MADT (if exists). There should only be one. */
+
+       for (i = 0; i < sdt_count; i++) {
+               if (sdt_entry[i].id != id)
+                       continue;
+               madt = (void *)
+                       __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
+               if (!madt) {
+                       printk(KERN_WARNING PREFIX "Unable to map %s\n",
+                               acpi_table_signatures[id]);
+                       return -ENODEV;
+               }
+               break;
+       }
+
+       if (!madt) {
+               printk(KERN_WARNING PREFIX "%s not present\n",
+                       acpi_table_signatures[id]);
+               return -ENODEV;
+       }
+
+       madt_end = (unsigned long) madt + sdt_entry[i].size;
+
+       /* Parse all entries looking for a match. */
+
+       entry = (acpi_table_entry_header *)
+               ((unsigned long) madt + madt_size);
+
+       while (((unsigned long) entry) + sizeof(acpi_table_entry_header) < madt_end) {
+               if (entry->type == entry_id) count++;
+
+               entry = (acpi_table_entry_header *)
+                       ((unsigned long) entry + entry->length);
+       }
+
+       return count;
+}
+
+
+int __init
+acpi_table_count_madt (enum acpi_madt_entry_id id)
+{
+       return acpi_table_count_madt_family(ACPI_APIC, sizeof(struct acpi_table_madt), id);
+}
index b84f047651d91cb3a5bcb1b10e116f9306da5e57..f8e3a1bdefd2c87ee08b371b3cc47f71b621e314 100644 (file)
@@ -390,6 +390,7 @@ int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler h
 void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr);
 void acpi_table_print_madt_entry (acpi_table_entry_header *madt);
 void acpi_table_print_srat_entry (acpi_table_entry_header *srat);
+int acpi_table_count_madt (enum acpi_madt_entry_id id);
 
 /* the following four functions are architecture-dependent */
 void acpi_numa_slit_init (struct acpi_table_slit *slit);